import { Controller, Get, Post, Body, Param, Put, Delete, Res, Req, QueryParams } from 'routing-controllers';
import { Container } from 'typedi';
import { DepartmentService } from '@services/department.service';
import { CreateDepartmentDto, DeptPageDto, UpdateDepartmentDto } from '@/dtos';
import { Log, LogOperation } from '@decorators/logs.decorators';
import { OpenAPI } from 'routing-controllers-openapi';
import { ApiResponseBuilder } from '@utils/api-response-builder';
import { Request, Response } from 'express';
import { RequiredPerm } from '@decorators/perm.decorator';
import { BadRequestException } from '@/exceptions';
import { RequestWithUser } from '@/interfaces';

@Controller('/departments')
export class DepartmentController {
  private department = Container.get(DepartmentService);

  @Get('/page')
  @RequiredPerm('department:page')
  @OpenAPI({ summary: '获取部门分页' })
  async findAll(@QueryParams() pageDto: DeptPageDto, @Req() req: Request, @Res() res: Response) {
    const { list, total } = await this.department.findAllWithChildren(pageDto);
    return new ApiResponseBuilder(req, res).paginate(list, total, pageDto.pageNum || 1, pageDto.pageSize || 20);
  }

  @Get('/detail/:id')
  @RequiredPerm('department:detail')
  @OpenAPI({ summary: '获取部门详情' })
  async findOne(@Param('id') id: number, @Req() req: Request, @Res() res: Response) {
    const result = await this.department.findOne(id);
    return new ApiResponseBuilder(req, res).success(result);
  }

  @Get('/all')
  @RequiredPerm('department:all')
  @OpenAPI({ summary: '获取所有部门' })
  async findAllTree(@Req() req: Request, @Res() res: Response) {
    const result = await this.department.getAllDepartment();
    return new ApiResponseBuilder(req, res).success(result);
  }

  @Get('/all/self')
  @RequiredPerm('department:all:self')
  @OpenAPI({ summary: '获取所属部门及其子部门' })
  async findAllBySelf(@Req() req: RequestWithUser, @Res() res: Response) {
    const { departmentId, roles } = req.user;
    const result = await this.department.getAllDepartmentBySelf(departmentId, roles);
    return new ApiResponseBuilder(req, res).success(result);
  }

  @Post('/create')
  @RequiredPerm('department:create')
  @OpenAPI({ summary: '创建部门' })
  @Log({
    bizType: 'department',
    operation: LogOperation.CREATE,
    bizId: (req: { user: { id: string } }) => `department:create:${req?.user?.id ?? ''}`,
  })
  async create(@Body() dto: CreateDepartmentDto, @Res() res: Response, @Req() req: Request) {
    await this.department.create(dto);
    return new ApiResponseBuilder(req, res).success();
  }

  @Put('/update/:id')
  @RequiredPerm('department:update')
  @OpenAPI({ summary: '更新部门' })
  @Log({
    bizType: 'department',
    operation: LogOperation.UPDATE,
    bizId: (req: { user: { id: string } }) => `department:update:${req?.user?.id ?? ''}`,
  })
  async update(@Param('id') id: number, @Body() dto: UpdateDepartmentDto, @Res() res: Response, @Req() req: Request) {
    await this.department.update(id, dto);
    return new ApiResponseBuilder(req, res).success();
  }

  @Delete('/delete/:ids')
  @RequiredPerm('department:delete')
  @OpenAPI({ summary: '删除部门' })
  @Log({
    bizType: 'department',
    operation: LogOperation.DELETE,
    bizId: (req: { user: { id: string } }) => `department:delete:${req?.user?.id ?? ''}`,
  })
  async remove(@Param('ids') idsRaw: string, @Res() res: Response, @Req() req: Request) {
    const ids: number[] = idsRaw
      .split(',')
      .map(Number)
      .filter(n => !Number.isNaN(n));
    if (!ids.length) throw new BadRequestException('ids 不能为空');
    await this.department.remove(ids);
    return new ApiResponseBuilder(req, res).success();
  }
}
